package com.virtualmall.controller;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
//import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.virtualmall.bean.Account;
import com.virtualmall.bean.Address;
import com.virtualmall.common.Constants;
import com.virtualmall.service.AccountService;
import com.virtualmall.service.AddressService;
import com.virtualmall.service.ShoppingCartService;

@Controller
public class UserController {
	
	//private Logger logger = Logger.getLogger(UserController.class);
	
	@Autowired
	private AccountService accountService;

	@Autowired
	private AddressService addressService;
	
    @Autowired
    private ShoppingCartService shoppingCartService;

    @RequestMapping(value="/account/login",method=RequestMethod.POST)
    @ResponseBody
    public Map<String,String> login(String accountName,String pwd,HttpServletRequest request){
        //logger.info("login() method begin...");

        Account loginUser = new Account();
        loginUser.setUserName(accountName);
        loginUser.setPassword(pwd);
        
        List<Account> accountList = this.accountService.read(loginUser);

        Map<String,String> result = new HashMap<String,String>();
        
        if(StringUtils.isNotEmpty(loginUser.getUserName()) && CollectionUtils.isNotEmpty(accountList) && accountList.size()>0){
            Account account = accountList.get(0);
            Date lastLoginDate = account.getLastLoginDate();

            account.setOnlineStatus(Constants.ACCOUNT_STATUS_ONLINE);
            account.setLastLoginDate(new Date());
            this.accountService.update(account);

            account.setPassword(null);
            
            request.getSession().setAttribute(Constants.USER_ID_SESSION, account.getId());
            request.getSession().setAttribute(Constants.USER_ACCOUNT_SESSION, account);
            request.getSession().setAttribute(Constants.USER_LAST_LOGIN_DATE, lastLoginDate);
            
            result.put("result", Constants.SUCCESS_RESULT_FLAG);
            
            if(Constants.ACCOUNT_TYPE_CUSTOMER.equals(account.getAccountType())){
                result.put("redirectUrl", "home");
            }else if(Constants.ACCOUNT_TYPE_MERCHANT.equals(account.getAccountType())){
                result.put("redirectUrl", "merchant/home");
            }else{
                result.put("redirectUrl", "customerService/home");
            }
        }else{
            result.put("result", Constants.FAILURE_RESULT_FLAG);
        }
        
        //logger.info("login() method end...");
        
        return result;
    }
    
    @RequestMapping(value="/account/logout",method=RequestMethod.GET)
	public String logout(HttpServletRequest request){
        //logger.info("logout() method begin...");

        Account account = this.accountService.read((Long)request.getSession().getAttribute(Constants.USER_ID_SESSION));
        
        account.setOnlineStatus(Constants.ACCOUNT_STATUS_OFFLINE);
        this.accountService.update(account);
        
        request.getSession().invalidate();

        //logger.info("logout() method end...");
        
        return "redirect:/";
	}
    
    @RequestMapping(value="/account/register",method=RequestMethod.POST)
    @ResponseBody
    public Map<String,String> register(Account account,HttpServletRequest request) {
        //logger.info("register() method begin...");

        Map<String,String> result = new HashMap<String,String>();

        
        Address address = new Address();
        this.addressService.create(address);
        
        account.setAddress(address);
        account.setAccountType(Constants.ACCOUNT_TYPE_CUSTOMER);
        account.setLastLoginDate(new Date());
        this.accountService.create(account);

        account.setPassword(null);
        
        request.getSession().setAttribute(Constants.USER_ID_SESSION, account.getId());
        request.getSession().setAttribute(Constants.USER_ACCOUNT_SESSION, account);

        result.put("result", Constants.SUCCESS_RESULT_FLAG);
        result.put("redirectUrl", "registerSuccess");
        
        //logger.info("register() method end...");
        
        return result;
    }

    @RequestMapping(value="/registerSuccess",method=RequestMethod.GET)
    public String registerSuccess() {
        return "/registerSuccess.jsp";
    }
    
    @RequestMapping(value="/home")
    public ModelAndView home(ModelMap modelMap,HttpServletRequest request){
    	
        ModelAndView mav = new ModelAndView("/customer/index.jsp", modelMap);
        
        return mav;
    }

    @RequestMapping(value="/merchant/home")
    public ModelAndView merchantHome(ModelMap modelMap,HttpServletRequest request){
        
        ModelAndView mav = new ModelAndView("/merchant/index.jsp", modelMap);
        
        return mav;
    }

    @RequestMapping(value="/customerService/home")
    public ModelAndView customerServiceHome(ModelMap modelMap,HttpServletRequest request){
        
        ModelAndView mav = new ModelAndView("/customerService/index.jsp", modelMap);
        
        return mav;
    }
    
    @RequestMapping(value="/account/modifyPassword",method=RequestMethod.POST)
    @ResponseBody
    public Map<String,String> modifyPassword(String originalPassword,String newPassword,HttpServletRequest request){
        //logger.info("modifyPassword() method begin...");

        Account account = this.accountService.read((Long)request.getSession().getAttribute(Constants.USER_ID_SESSION));

        Map<String,String> result = new HashMap<String,String>();
        
        if(account.getPassword().equals(originalPassword)){
            account.setPassword(newPassword);
            
            this.accountService.update(account);

            result.put("result", Constants.SUCCESS_RESULT_FLAG);
        }else{
            result.put("result", Constants.FAILURE_RESULT_FLAG);
            result.put("tips", "您输入的当前密码错误，请重新输入！");
        }
        
        //logger.info("modifyPassword() method end...");
        
        return result;
    }

    @RequestMapping(value="/account/userInfo",method=RequestMethod.GET)
    @ResponseBody
    public Map<String,Object> currentUserInfo(HttpServletRequest request){
        //logger.info("currentUserInfo() method begin...");

        Account account = this.accountService.read((Long)request.getSession().getAttribute(Constants.USER_ID_SESSION));
        account.setPassword(null);
        account.setLastLoginDate((Date)request.getSession().getAttribute(Constants.USER_LAST_LOGIN_DATE));
        
        Map<String,Object> result = new HashMap<String,Object>();
        
        result.put("result", Constants.SUCCESS_RESULT_FLAG);
        result.put("account", account);
        
        //logger.info("currentUserInfo() method end...");
        
        return result;
    }
    
    @RequestMapping(value="/account/update",method=RequestMethod.POST)
    @ResponseBody
    public Map<String,String> update(Account account){
        //logger.info("update() method begin...");

        Map<String,String> result = new HashMap<String,String>();
        
        try {
            Account acc = this.accountService.read(account.getId());
            acc.setNickName(account.getNickName());
            acc.setMerchantName(account.getMerchantName());
            acc.setBirthDay(account.getBirthDay());
            acc.setProvince(account.getProvince());
            acc.setCity(account.getCity());
            acc.setArea(account.getArea());
            acc.setTelephone(account.getTelephone());
            acc.setMobileNo(account.getMobileNo());
            
            this.accountService.update(acc);
            
            result.put("result", Constants.SUCCESS_RESULT_FLAG);
        } catch (Exception e) {
            //logger.error("update() method error...",e);
            
            result.put("result", Constants.FAILURE_RESULT_FLAG);
        }
        
        //logger.info("update() method end...");

        return result;
    }
    
    @RequestMapping(value="/account/statisticsInfo",method=RequestMethod.GET)
    @ResponseBody
    public Map<String,String> accountStatisticsInfo(Account account,HttpServletRequest request){
        //logger.info("accountStatisticsInfo() method begin...");

        Map<String,String> result = new HashMap<String,String>();
        
        try {
            Long userId = (Long)request.getSession().getAttribute(Constants.USER_ID_SESSION);
            
            Long shoppingCartCount = this.shoppingCartService.getShoppingCartListCount(userId);
            Double shoppingCartTotalPrice = this.shoppingCartService.getShoppingCartTotalPrice(userId);

            result.put("result", Constants.SUCCESS_RESULT_FLAG);
            result.put("shoppingCartCount", shoppingCartCount.toString());
            result.put("shoppingCartTotalPrice", shoppingCartTotalPrice==null?"0":shoppingCartTotalPrice.toString());
        } catch (Exception e) {
            //logger.error("accountStatisticsInfo() method error...",e);
            
            result.put("result", Constants.FAILURE_RESULT_FLAG);
        }
        
        //logger.info("accountStatisticsInfo() method end...");

        return result;
    }

    @RequestMapping(value="/account/createCustomerServiceAccount",method=RequestMethod.POST)
    @ResponseBody
    public Map<String,String> createCustomerServiceAccount(Account account){
        //logger.info("createCustomerServiceAccount() method begin...");

        Map<String,String> result = new HashMap<String,String>();
        
        try {
            account.setAccountType(Constants.ACCOUNT_TYPE_CUSTOMER_SERVICE);
            account.setOnlineStatus(Constants.ACCOUNT_STATUS_OFFLINE);
            account.setPassword("888888");
            this.accountService.create(account);
            
            result.put("result", Constants.SUCCESS_RESULT_FLAG);
        } catch (Exception e) {
            //logger.error("createCustomerServiceAccount() method error...",e);
            
            result.put("result", Constants.FAILURE_RESULT_FLAG);
        }
        
        //logger.info("createCustomerServiceAccount() method end...");

        return result;
    }

    @RequestMapping(value="/account/queryCustomerServiceAccountList",method=RequestMethod.GET)
    @ResponseBody
    public Map<String,Object> queryCustomerServiceAccountList(Account account){
        //logger.info("queryCustomerServiceAccountList() method begin...");

        Map<String,Object> result = new HashMap<String,Object>();
        
        try {
            List<Account> accountList = this.accountService.read(account);
            
            result.put("accountList", accountList);
            result.put("result", Constants.SUCCESS_RESULT_FLAG);
        } catch (Exception e) {
            //logger.error("queryCustomerServiceAccountList() method error...",e);
            
            result.put("result", Constants.FAILURE_RESULT_FLAG);
        }
        
        //logger.info("queryCustomerServiceAccountList() method end...");

        return result;
    }
    
    @RequestMapping(value="/account/deleteCustomerServiceAccount",method=RequestMethod.POST)
    @ResponseBody
    public Map<String,String> deleteCustomerServiceAccount(Account account){
        //logger.info("deleteCustomerServiceAccount() method begin...");

        Map<String,String> result = new HashMap<String,String>();
        
        try {
            account.setAccountType(Constants.ACCOUNT_TYPE_CUSTOMER_SERVICE);
            this.accountService.delete(account);
            
            result.put("result", Constants.SUCCESS_RESULT_FLAG);
        } catch (Exception e) {
            //logger.error("deleteCustomerServiceAccount() method error...",e);
            
            result.put("result", Constants.FAILURE_RESULT_FLAG);
        }
        
        //logger.info("deleteCustomerServiceAccount() method end...");

        return result;
    }

    @RequestMapping(value="/account/checkUserNameOnly",method=RequestMethod.POST)
    @ResponseBody
    public Map<String,String> checkUserNameOnly(Account account){
        //logger.info("deleteCustomerServiceAccount() method begin...");

        Map<String,String> result = new HashMap<String,String>();
        
        try {
            List<Account> accountList = this.accountService.read(account);
            if(CollectionUtils.isNotEmpty(accountList)&&accountList.size()>0){
                result.put("only", "false");
            }else{
                result.put("only", "true");
            }
            
            result.put("result", Constants.SUCCESS_RESULT_FLAG);
        } catch (Exception e) {
            //logger.error("deleteCustomerServiceAccount() method error...",e);
            
            result.put("result", Constants.FAILURE_RESULT_FLAG);
        }
        
        //logger.info("deleteCustomerServiceAccount() method end...");

        return result;
    }
    
    
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        dateFormat.setLenient(true);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(
                dateFormat, true));
    }
}
